
 1000   .LIF
 1010  *SAVE S.DP18 ADD & SUB
 1020  *--------------------------------
 1030  *      18-DIGIT DECIMAL FLOATING POINT
 1040  *      ADDITION AND SUBTRACTION
 1044  *--------------------------------
 1046  AS.OVRFLW  .EQ $E8D5
 1050  *--------------------------------
 1060  DAC           .BS 12
 1070  DAC.EXPONENT  .EQ DAC
 1080  DAC.HI        .EQ DAC+1
 1090  DAC.EXTENSION .EQ DAC+10
 1100  DAC.SIGN      .EQ DAC+11
 1110  *--------------------------------
 1120  ARG           .BS 12
 1130  ARG.EXPONENT  .EQ ARG
 1140  ARG.HI        .EQ ARG+1
 1150  ARG.EXTENSION .EQ ARG+10
 1160  ARG.SIGN      .EQ ARG+11
 1170  *--------------------------------
 1180  SWAP.ARG.DAC
 1190         LDY #11      SWAP 12 BYTES
 1200  .1     LDA ARG,Y
 1210         LDX DAC,Y
 1220         STA DAC,Y
 1230         TXA
 1240         STA ARG,Y
 1250         DEY
 1260         BPL .1
 1270         RTS
 1280  *--------------------------------
 1290  *      SUBTRACT DAC FROM ARG
 1300  * DAC = ARG - DAC
 1310  *--------------------------------
 1320  DSUB   LDA DAC.EXPONENT
 1330         BEQ SWAP.ARG.DAC  ARG-0=ARG
 1340         LDA DAC.SIGN
 1350         EOR #$80
 1360         STA DAC.SIGN
 1370  *--------------------------------
 1380  *      ADD ARG TO DAC
 1390  * DAC = ARG + DAC
 1400  *--------------------------------
 1410  DADD   LDA ARG.EXPONENT
 1420         BEQ .3       DAC+0=DAC
 1430  .1     SEC          COMPARE EXPONENTS
 1440         LDA DAC.EXPONENT
 1450         BEQ SWAP.ARG.DAC  ARG+0=ARG
 1460         SBC ARG.EXPONENT
 1470         BMI .8       ARG IS LARGER
 1480         JSR SHIFT.ARG.RIGHT.N
 1490         SED          SET DECIMAL MODE
 1500         LDA DAC.SIGN COMPARE SIGNS
 1510         EOR ARG.SIGN
 1520         BMI .4       OPPOSITE SIGNS
 1530  *---SAME SIGNS-------------------
 1540         CLC          SAME SIGNS, JUST ADD VALUES
 1550         LDY #9       TEN BYTES
 1560  .2     LDA DAC.HI,Y
 1570         ADC ARG.HI,Y
 1580         STA DAC.HI,Y
 1590         DEY
 1600         BPL .2
 1610         CLD          BINARY MODE
 1620         BCC .3       NO CARRY
 1630         JSR SHIFT.DAC.RIGHT.ONE
 1640         LDA DAC.HI
 1650         ORA #$10
 1660         STA DAC.HI
 1670  .3     RTS
 1680  *---DIFFERENT SIGNS--------------
 1690  .4     SEC          SUBTRACT ARG FROM FAC
 1700         LDY #9       TEN BYTES
 1710  .5     LDA DAC.HI,Y
 1720         SBC ARG.HI,Y
 1730         STA DAC.HI,Y
 1740         DEY
 1750         BPL .5
 1760         BCS .7       NO BORROW
 1770         SEC          BORROW, SO COMPLEMENT
 1780         LDY #9
 1790  .6     LDA #0
 1800         SBC DAC.HI,Y
 1810         STA DAC.HI,Y
 1820         DEY
 1830         BPL .6
 1840         LDA ARG.SIGN
 1850         STA DAC.SIGN
 1860  .7     CLD
 1870         JMP NORMALIZE.DAC
 1880  *---SWAP ARG & DAC, TRY AGAIN----
 1890  .8     JSR SWAP.ARG.DAC
 1900         JMP .1
 1910  *--------------------------------
 1920  *      SHIFT DAC RIGHT ONE DECIMAL DIGIT
 1930  *--------------------------------
 1940  SHIFT.DAC.RIGHT.ONE
 1950         INC DAC.EXPONENT
 1955         BMI .2
 1960         LDY #4       4 BITS RIGHT
 1970  .1     LSR DAC.HI
 1980         ROR DAC.HI+1
 1990         ROR DAC.HI+2
 2000         ROR DAC.HI+3
 2010         ROR DAC.HI+4
 2020         ROR DAC.HI+5
 2030         ROR DAC.HI+6
 2040         ROR DAC.HI+7
 2050         ROR DAC.HI+8
 2060         ROR DAC.HI+9 EXTENSION
 2070         DEY
 2080         BNE .1
 2090         RTS
 2095  .2     JMP AS.OVRFLW
 2100  *--------------------------------
 2110  *      SHIFT ARG RIGHT N DIGITS
 2120  *--------------------------------
 2130  SHIFT.ARG.RIGHT.N
 2140         LDY #9       SET UP FOR 10 BYTES
 2150         CMP #20      DON'T BOTHER IF OFF END
 2160         BCS .4       JUST ENTER ZERO INTO ARG
 2170         LSR          TEST SHIFT COUNT ODD OR EVEN
 2180         BCC .2       EVEN
 2190         JSR SHIFT.ARG.RIGHT.ONE
 2200  .2     TAY          # BYTES TO SHIFT
 2210         BEQ .6       NONE
 2220         EOR #$FF     -(#BYTES+1)
 2230         CLC
 2240         ADC #10      9-#BYTES
 2250         TAX
 2260         LDY #9
 2270  .3     LDA ARG.HI,X
 2280         STA ARG.HI,Y
 2290         DEY
 2300         DEX
 2310         BPL .3
 2320  .4     LDA #0
 2330  .5     STA ARG.HI,Y
 2340         DEY
 2350         BPL .5
 2360  .6     RTS
 2370  *--------------------------------
 2380  *      NORMALIZE VALUE IN DAC
 2390  *--------------------------------
 2400  NORMALIZE.DAC
 2410         LDY #-1
 2420  .1     INY          NEXT BYTE
 2430         CPY #10
 2440         BCS .7       ...NO MORE BYTES
 2450         LDA DAC.HI,Y
 2460         BEQ .1       ...STILL ZEROES
 2500  *--------------------------------
 2510  .2     TYA          TEST BYTE COUNT
 2520         BEQ .5       FIRST BYTE IS NON-ZERO
 2530         LDX #0       POINT X AT FIRST BYTE
 2540  .3     LDA DAC.HI,Y
 2550         STA DAC.HI,X
 2560         INX
 2570         INY
 2580         CPY #10
 2590         BCC .3
 2600  *--------------------------------
 2610         LDA #0       FILL REST OF DAC WITH ZEROES
 2620  .4     STA DAC.HI,X
 2630         DEC DAC.EXPONENT  ADJUST EXPONENT
 2640         DEC DAC.EXPONENT  FOR SHIFT DISTANCE
 2650         INX
 2660         CPX #10
 2670         BCC .4
 2680  *--------------------------------
 2690  .5     LDA DAC.HI   SEE IF NEED ONE-DIGIT SHIFT
 2700         AND #$F0
 2710         BNE .6       NO NYBBLE SHIFT NEEDED
 2720         DEC DAC.EXPONENT
 2730         JSR SHIFT.DAC.LEFT.ONE
 2740  .6     LDA DAC.EXPONENT
 2741         BPL .8
 2742  .7     LDA #0
 2743         STA DAC.EXPONENT
 2744         STA DAC.SIGN
 2745  .8     RTS
 2750  *--------------------------------
 2760  SHIFT.DAC.LEFT.ONE
 2770         LDY #4
 2780  .1     ASL DAC.EXTENSION
 2790         ROL DAC.HI+8
 2800         ROL DAC.HI+7
 2810         ROL DAC.HI+6
 2820         ROL DAC.HI+5
 2830         ROL DAC.HI+4
 2840         ROL DAC.HI+3
 2850         ROL DAC.HI+2
 2860         ROL DAC.HI+1
 2870         ROL DAC.HI
 2880         DEY
 2890         BNE .1
 2900         RTS
 2910  *--------------------------------
 2920  *      SHIFT ARG RIGHT ONE DECIMAL DIGIT
 2930  *--------------------------------
 2940  SHIFT.ARG.RIGHT.ONE
 2950         LDY #4
 2960  .1     LSR ARG.HI
 2970         ROR ARG.HI+1
 2980         ROR ARG.HI+2
 2990         ROR ARG.HI+3
 3000         ROR ARG.HI+4
 3010         ROR ARG.HI+5
 3020         ROR ARG.HI+6
 3030         ROR ARG.HI+7
 3040         ROR ARG.HI+8
 3050         ROR ARG.HI+9  EXTENSION
 3060         DEY
 3070         BNE .1
 3080         RTS
 3090  *--------------------------------

